package com.zzf.concurrent.example.graceful.interrupt;

import lombok.extern.slf4j.Slf4j;

/**
 *
 * 思路： 利用守护线程的特性来实现强制中断
 * @author GaoFeng2017
 * @date 2019/8/5 23:43
 */

@Slf4j
public class ThreadService {

    /** 执行线程 */
    private Thread executeThread;

    /** 线程是否执行完成 */
    private boolean finished = false;


    public void execute(Runnable task) {

        this.executeThread = new Thread(() -> {

            Thread taskThread = new Thread(task);
            taskThread.setDaemon(true);
            taskThread.start();
            log.info("taskThread is start...");

            try {
                taskThread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
                log.info("join interrupted");
            }

            // 正常执行完或超时打断，如果是正常执行，应该提前结束。
            this.finished = true;

        });

        this.executeThread.start();
    }

    public void shutdown(long ms) {
        long startTime = System.currentTimeMillis();

        while (!this.finished) {
            long currentTimeMillis = System.currentTimeMillis();

            if (currentTimeMillis - startTime > ms) {
                log.info("已超时，强制关闭子线程");
                executeThread.interrupt();
                break;
            }
            try {
                // 不能使用Thread或currentThread, 因为该类线程为调用方线程。
                executeThread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
                log.info("执行线程被打断！");
                break;
            }
        }

        // 重置标记
        this.finished = false;
    }

    public Thread getExecuteThread() {
        return executeThread;
    }

    public boolean isFinished() {
        return finished;
    }
}
